<?php
/**
 * Copyright (c) 2006-2008, Julien PORTALIER
 * 
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 * 
 * @copyright    Copyright (c) 2006-2008, Julien PORTALIER
 * @link         http://feather-cm.googlecode.com/
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

class AuthComponent
{
	protected $Session;
	protected $controller;
	
	public    $identified = false;
	public    $id         = 'Anonymous';
	public    $groups     = array('anonymous');
	
	/**
	 * @todo Login on main site should be done throught a webservice instead.
	 */
	function startup(Controller $controller)
	{
		$this->controller = $controller;
		$this->Session    = $controller->Session;
		
		if ($this->Session->check('Member'))
		{
			# already signed-in
			$this->login($this->Session->read('Member'));
		}
		elseif (Cookies::check(Core::auth_cookie))
		{
			#. login is done on main site
			if (env("HTTP_HOST") != FULL_DOMAIN)
			{
				$here = PROTOCOL.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
				HTTP::redirect(MAIN_SITE_URL.'/members/auto_login?redirect='.urlencode($here));
			}
			
			#. otherwise: auto sign-in
			list($uid, $pwd) = Cookies::read(Core::auth_cookie);
			$member = $controller->load->model('Member');
			$data   = $member->login($uid, $pwd);
			
			# valid account?
			if (is_array($data))
			{
				$this->login($data);
				return;
			}
			
			# invalid account
			$this->logout();
		}
	}
	
	// authentification
	
	/**
	 * Authenticates current user.
	 */
	function login(array &$member)
	{
		$this->__setMember(true, $member['id'], $member['groups']);
		$data = array(
			'id'     => $member['id'],
			'groups' => $member['groups']
		);
		$this->Session->write('Member', &$data);
	}
	
	/**
	 * Deauthenticates current user.
	 */
	function logout()
	{
		$this->__setMember(false, 'Anonymous', array('anonymous'));
		$this->Session->delete('Member');
		Cookies::delete(Core::auth_cookie);
	}
	
	/**
	 * Remember current user after a successfull login.
	 */
	function remember($uid, $pwd, $set=true)
	{
		if ($set)
		{
			$data = array($uid, $pwd);
			Cookies::write(Core::auth_cookie, $data);
		}
		else {
			Cookies::delete(Core::auth_cookie);
		}
	}
	
	/**
	 * Stores and retrieves informations saved in a cookie on current anonymous user.
	 */
	function rememberAnonymous($data=null)
	{
		if ($data === false) {
			Cookies::delete('FeatherRememberAnonymous');
		}
		elseif (empty($data))
		{
			$data = Cookies::check('FeatherRememberAnonymous') ?
				Cookies::read('FeatherRememberAnonymous') : array();
			$data['remember_me'] = true;
			return $data;
		}
		else
		{
			$tmp = array(
				'user_name'   => $data['user_name'],
				'user_email'  => $data['user_email'],
				'user_url'    => $data['user_url']
			);
			Cookies::write('FeatherRememberAnonymous', &$tmp);
		}
	}
	
	// rights
	
	/**
	 * Is current user member of any of these groups?
	 */
	function inGroup($groups)
	{
		if (!is_array($groups))
			$groups = explode(',', str_replace(' ', '', $groups));
		$groups = array_intersect($this->groups, $groups);
		return !empty($groups);
	}
	
	/**
	 * Is current user an admin?
	 */
	function isAdmin()
	{
		return $this->inGroup(Core::admins);
	}
	
	/**
	 * Permission denied to access the current page.
	 */
	function permissionDenied()
	{
		if ($this->identified)
		{
			$url = empty($this->controller->params['url']['referer']) ? '/' :
				$this->controller->params['url']['referer'];
			$this->controller->flash(_('Permission denied'), $url, 'error', 403);
		}
		else
		{
			$here = PROTOCOL.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
			$this->controller->flash(_('Access is restricted, please sign in'),
				MAIN_SITE_URL.'/members/login?redirect='.urlencode($here), 'warning');
		}
	}
	
	/**
	 * Checks a referer to prevent endless loops in redirections.
	 */
	function checkReferer($referer)
	{
		return !(empty($referer) or preg_match(':/members/(register|reminder|login|logout):', $referer));
	}
	
	
	// internals
	
	protected function __setMember($identified, $id, array $groups)
	{
		$this->identified =  $identified;
		$this->id         =  $id;
		$this->groups     =& $groups;
	}
}
?>